package meb

import (
	"context"
	"encoding/json"
	"errors"
	"github.com/gin-gonic/gin"
	"github.com/mosongcc/gotool/gtime"
	"github.com/wechatpay-apiv3/wechatpay-go/core"
	"github.com/wechatpay-apiv3/wechatpay-go/services/payments/jsapi"
	"github.com/wechatpay-apiv3/wechatpay-go/services/payments/native"
	"strings"
	"vitepress-serve/internal/common/hgin"
	"vitepress-serve/internal/model"
)

//deprecated 2024.09.09 改为使用：pay_page

// OrderWxpay 微信支付发起
func (ctl *Controller) OrderWxpay(ctx *gin.Context) (err error) {
	var (
		args     = hgin.ApiReq[OrderWxpayArgs](ctx)
		isWechat = strings.Contains(strings.ToLower(ctx.Request.UserAgent()), "micromessenger") //是否是微信访问 true=是 false=否
	)

	var order model.Order
	if err = ctl.db.Where("order_id = ?", args.OrderId).Take(&order).Error; err != nil {
		return
	}
	if order.Status != model.ORDER_STATUS_PENDING {
		err = errors.New("订单当前状态不能继续支付")
		return
	}

	if isWechat {
		err = jsapiPay(ctl, ctx, order)
		if err != nil {
			return
		}
		return
	}

	err = nativePay(ctl, ctx, order)
	if err != nil {
		return
	}

	return
}

func getNotifyUrl(safeUrl, mchid, orderId string) string {
	if safeUrl[len(safeUrl)-1:] == "/" {
		safeUrl = safeUrl[:len(safeUrl)-1]
	}
	notifyUrl := safeUrl + PATH_WXPAY_NOTIFY
	notifyUrl = strings.ReplaceAll(notifyUrl, ":mchid", mchid)
	notifyUrl = strings.ReplaceAll(notifyUrl, ":order_id", orderId)
	return notifyUrl
}

func jsapiPay(ctl *Controller, ctx *gin.Context, order model.Order) (err error) {
	var (
		wx    = ctl.ConfigService.Wechat()
		zf    = ctl.ConfigService.Wxpay()
		appid = wx.Appid
		mchid = zf.Mchid
	)
	var uo model.UserOauth
	if err = ctl.db.Where("uid = ? and appid = ?", order.Uid, appid).Take(&uo).Error; err != nil {
		return
	}
	var openid = uo.Openid

	jsapiService, err := ctl.WxpayService.Jsapi()
	if err != nil {
		return
	}
	resp, _, err := jsapiService.PrepayWithRequestPayment(context.Background(), jsapi.PrepayRequest{
		Appid:         core.String(appid),
		Mchid:         core.String(mchid),
		Description:   core.String(order.ProdName),
		OutTradeNo:    core.String(order.OrderId),
		TimeExpire:    core.Time(gtime.ParseT14(order.PayTimeout)),
		Attach:        core.String(""),
		NotifyUrl:     core.String(getNotifyUrl(zf.SafeUrl, mchid, order.OrderId)),
		GoodsTag:      core.String(""),
		LimitPay:      []string{},
		SupportFapiao: core.Bool(false),
		Amount: &jsapi.Amount{
			Total: core.Int64(int64(order.TxnAmt)),
		},
		Payer:     &jsapi.Payer{Openid: core.String(openid)},
		Detail:    nil,
		SceneInfo: nil,
		SettleInfo: &jsapi.SettleInfo{
			ProfitSharing: core.Bool(false),
		},
	})
	if err != nil {
		return
	}
	rBytes, err := json.Marshal(resp)
	if err != nil {
		return
	}
	payinfo := string(rBytes)
	hgin.ApiRes(ctx, OrderWxpayBody{Payinfo: payinfo})
	return
}

func nativePay(ctl *Controller, ctx *gin.Context, order model.Order) (err error) {
	var (
		wx    = ctl.ConfigService.Wechat()
		zf    = ctl.ConfigService.Wxpay()
		appid = wx.Appid
		mchid = zf.Mchid
	)
	nativeService, err := ctl.WxpayService.Native()
	if err != nil {
		return
	}
	resp, _, err := nativeService.Prepay(context.Background(), native.PrepayRequest{
		Appid:         core.String(appid),
		Mchid:         core.String(mchid),
		Description:   core.String(order.ProdName),
		OutTradeNo:    core.String(order.OrderId),
		TimeExpire:    core.Time(gtime.ParseT14(order.PayTimeout)),
		Attach:        core.String(""),
		NotifyUrl:     core.String(getNotifyUrl(zf.SafeUrl, mchid, order.OrderId)),
		GoodsTag:      core.String(""),
		LimitPay:      []string{},
		SupportFapiao: core.Bool(false),
		Amount: &native.Amount{
			Total: core.Int64(int64(order.TxnAmt)),
		},
		Detail: nil,
		SettleInfo: &native.SettleInfo{
			ProfitSharing: core.Bool(false),
		},
		SceneInfo: nil,
	})
	if err != nil {
		return
	}
	codeUrl := *resp.CodeUrl
	hgin.ApiRes(ctx, OrderWxpayBody{CodeUrl: codeUrl})
	return
}

type OrderWxpayArgs struct {
	OrderId string `json:"order_id"`
}

type OrderWxpayBody struct {
	//手机微信支付
	Payinfo string `json:"payinfo,omitempty"`
	//PC网页支付 二维码链接
	CodeUrl string `json:"code_url,omitempty"`
}
